﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using HadronData;

namespace Hadron.Entities
{
    class Switch
        : LandEntity
    {
        private bool m_bActivated;
        private double m_dTime;
        private Polygon m_polygonGeometryLocal, m_polygonGeometryWorld;

        public Switch(EntityMarker p_entityMarker, Environment p_environment)
            : base(p_entityMarker, p_environment)
        {
            m_nHealth = int.MaxValue;

            m_polygonGeometryLocal = new Polygon();
            m_polygonGeometryLocal.Edges.Add(new Edge(-10.0f,   0.0f, -8.0f,  -6.0f, Color.Gray));
            m_polygonGeometryLocal.Edges.Add(new Edge( 10.0f,   0.0f,  8.0f,  -6.0f, Color.Gray));
            m_polygonGeometryLocal.Edges.Add(new Edge( -8.0f,  -6.0f,  8.0f,  -6.0f, Color.DimGray));

            m_polygonGeometryLocal.Edges.Add(new Edge( -7.0f,  -6.0f, -2.0f, -10.0f, Color.YellowGreen));
            m_polygonGeometryLocal.Edges.Add(new Edge(  7.0f,  -6.0f,  2.0f, -10.0f, Color.YellowGreen));
            m_polygonGeometryLocal.Edges.Add(new Edge( -2.0f, -10.0f,  2.0f, -10.0f, Color.YellowGreen));

            m_polygonGeometryWorld = new Polygon(m_polygonGeometryLocal);

            m_circleBounds = m_polygonGeometryLocal.GetBoundingCircle(Vector2.Zero);
        }

        public override void Update(GameTime p_gameTime)
        {
            if (m_edgeAnchor == null)
            {
                m_entityStatus = EntityStatus.Deactivated;
                return;
            }

            base.Update(p_gameTime);

            m_circleBounds.Centre = m_trnPlacement.Translation;

            m_dTime = p_gameTime.TotalGameTime.TotalSeconds;

            m_nHealth = int.MaxValue;

            m_polygonGeometryWorld.Transform(m_trnPlacement, m_polygonGeometryLocal);

            // light oscillation
            float fOpacity = 0.75f + (float)Math.Cos(m_dTime * MathHelper.TwoPi) * 0.25f;
            Color colourLight = m_polygonGeometryWorld.Edges[4].Colour;
            colourLight.A = (byte)(fOpacity * 255.0f);
            for (int nIndex = 3; nIndex < 6; nIndex++)
                m_polygonGeometryWorld.Edges[nIndex].Colour = colourLight;

        }

        public override void Draw(SpriteBatch p_spriteBatch)
        {
            m_polygonGeometryWorld.Draw(p_spriteBatch);

            // arrow
            if (!m_bActivated)
            {
                float fOffset = (float)((m_dTime * 10.0 + 5.0) % 10.0);
                float fIntensity = 1.0f - fOffset * 0.1f;
                p_spriteBatch.Draw(AssetManager.Textures.StationArrow, Position, null,
                    new Color(fIntensity, fIntensity, fIntensity),
                    Orientation, new Vector2(32.0f, 64.0f - fOffset), 1.0f, SpriteEffects.None, 0.0f);
            }
        }

        public override void OnProjectileHit()
        {
            if (m_bActivated)
                return;

            // activate
            m_bActivated = true;

            // switch light colour to red
            for (int nIndex = 3; nIndex < 6; nIndex++)
                m_polygonGeometryWorld.Edges[nIndex].Colour = Color.Red;

            // open matching gates
            String strGateKey = m_entityMarker.Name.Replace("Switch", "");
            foreach (Entity entity in m_environment.Entities)
            {
                if (entity.Type != EntityType.SwitchGate)
                    continue;

                Gate gate = (Gate)entity;
                if (gate.Open)
                    continue;

                if (gate.Marker.Name.Replace("Gate", "") == strGateKey)
                    gate.Open = true;
            }
        }

        public override EntityType Type
        {
            get { return EntityType.Switch; }
        }

        public override bool Hostile
        {
            get { return true; }
        }

        public override bool Destructuble
        {
            get { return false; }
        }

        public override Geometry Geometry
        {
            get { return m_polygonGeometryWorld; }
        }
    }
}
